package cn.td0f7.android.wangzhongcourse.netword;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

import cn.td0f7.android.wangzhongcourse.R;
import cn.td0f7.android.wangzhongcourse.entity.ProgressListener;
import cn.td0f7.android.wangzhongcourse.entity.ProgressModel;
import cn.td0f7.android.wangzhongcourse.utils.OkhttpUtil;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.BufferedSink;
import okio.Okio;
import okio.Sink;

public class NetworkRequestActivity extends AppCompatActivity {
    private Context context = this;
    private String TAG = "推动学堂";
    private TextView tvContent;
    private Button btGet, btGetParams, btGetParamsAndHandler, btPost, btPut, btPostFormdata, btUpload, btDownload, btDownloadProgress;
    private String url = "https://api.td0f7.cn/dio-okhttp/okhttp/";
    private Handler handler;
    private OkHttpClient client;
    private String[] permissions = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE,};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_network_request);
        initPermission();
        client = new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .callTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .build();
        btDownload = findViewById(R.id.btDownload);
        btPostFormdata = findViewById(R.id.btPostFormdata);
        tvContent = findViewById(R.id.tvContent);
        btGet = findViewById(R.id.btGet);
        btGetParams = findViewById(R.id.btGetParams);
        btGetParamsAndHandler = findViewById(R.id.btGetParamsAndHandler);
        btPost = findViewById(R.id.btPost);
        btPut = findViewById(R.id.btPut);
        btUpload = findViewById(R.id.btUpload);
        btDownloadProgress = findViewById(R.id.btDownloadProgress);
        handler = new Handler() {
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);
                Toast.makeText(context, " " + msg.obj, Toast.LENGTH_SHORT).show();
                tvContent.setText(msg.obj.toString());
            }
        };
        btGet.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                get();
            }
        });
        btGetParams.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getParams();
            }
        });
        btGetParamsAndHandler.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getParamsAndHandler();
            }
        });
        btPut.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                put();
            }
        });
        btPost.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                post();
            }
        });
        btPostFormdata.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                postFormdata();
            }
        });
        btUpload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                upload();
            }
        });
        btDownload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread() {
                    @Override
                    public void run() {
                        super.run();
                        download();
                    }
                }.start();
            }
        });
        btDownloadProgress.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread() {
                    @Override
                    public void run() {
                        super.run();
                        downloadProgress();
                    }
                }.start();
            }
        });
    }

    private void initPermission() {
        ArrayList<String> toApplyList = new ArrayList<>();//无权限集合

        for (String perm : permissions) {
            if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this, perm)) {
                toApplyList.add(perm);
                //进入到这里代表没有权限.
            }
        }
        String tmpList[] = new String[toApplyList.size()];
        if (!toApplyList.isEmpty()) {
            ActivityCompat.requestPermissions(this, toApplyList.toArray(tmpList), 123);
        }
    }

    private void get() {
        Request request = new Request.Builder()
                .url(url)
                .build();

        new Thread() {
            @Override
            public void run() {
                super.run();
                Message msg = handler.obtainMessage(1);
                try (Response response = client.newCall(request).execute()) {
                    msg.obj = response.body().string();
                } catch (Exception e) {
                    e.printStackTrace();
                    msg.obj = e.getMessage();
                } finally {
                    handler.sendMessage(msg);
                }
            }
        }.start();
    }

    private void getParams() {
        Request request = new Request.Builder()
                .url(url + "params?name=推动学堂&age=10")
                .build();

        new Thread() {
            @Override
            public void run() {
                super.run();
                Message msg = handler.obtainMessage(1);
                try (Response response = client.newCall(request).execute()) {
                    msg.obj = response.body().string();
                } catch (Exception e) {
                    e.printStackTrace();
                    msg.obj = e.getMessage();
                } finally {
                    handler.sendMessage(msg);
                }
            }
        }.start();
    }

    private void getParamsAndHandler() {
        Request request = new Request.Builder()
                .url(url + "paramsAndHandler?name=推动学堂&age=10")
                .addHeader("token", "dsadsa")
                .build();

        new Thread() {
            @Override
            public void run() {
                super.run();
                Message msg = handler.obtainMessage(1);
                try (Response response = client.newCall(request).execute()) {
                    msg.obj = response.body().string();
                } catch (Exception e) {
                    e.printStackTrace();
                    msg.obj = e.getMessage();
                } finally {
                    handler.sendMessage(msg);
                }
            }
        }.start();
    }

    private void put() {
        RequestBody body = RequestBody.create(MediaType.get("application/json"), "推动学堂 www.td0f7.cn");

        Request request = new Request.Builder()
                .url(url)
                .put(body)
                .build();

        new Thread() {
            @Override
            public void run() {
                super.run();
                Message msg = handler.obtainMessage(1);
                try (Response response = client.newCall(request).execute()) {
                    msg.obj = response.body().string();
                } catch (Exception e) {
                    e.printStackTrace();
                    msg.obj = e.getMessage();
                } finally {
                    handler.sendMessage(msg);
                }
            }
        }.start();
    }

    private void post() {
        RequestBody body = RequestBody.create(MediaType.get("application/json"), "推动学堂 www.td0f7.cn");

        Request request = new Request.Builder()
                .url(url + "body")
                .post(body)
                .build();

        new Thread() {
            @Override
            public void run() {
                super.run();
                Message msg = handler.obtainMessage(1);
                try (Response response = client.newCall(request).execute()) {
                    msg.obj = response.body().string();
                } catch (Exception e) {
                    e.printStackTrace();
                    msg.obj = e.getMessage();
                } finally {
                    handler.sendMessage(msg);
                }
            }
        }.start();
    }

    private void postFormdata() {
        RequestBody body = new FormBody.Builder()
                .add("id", "2")
                .add("name", "td0f7")
                .build();

        Request request = new Request.Builder()
                .url(url + "fdata")
                .post(body)
                .build();

        new Thread() {
            @Override
            public void run() {
                super.run();
                Message msg = handler.obtainMessage(1);
                try (Response response = client.newCall(request).execute()) {
                    msg.obj = response.body().string();
                } catch (Exception e) {
                    e.printStackTrace();
                    msg.obj = e.getMessage();
                } finally {
                    handler.sendMessage(msg);
                }
            }
        }.start();
    }

    private void upload() {
        File file = new File("/storage/emulated/0/DCIM/Camera/1.jpg");
        RequestBody requestBody = RequestBody.create(MediaType.get("multipart/form-data"), file);

        RequestBody body = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("file", file.getName(), requestBody)
                .build();

        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();

        new Thread() {
            @Override
            public void run() {
                super.run();
                Message msg = handler.obtainMessage(1);
                try (Response response = client.newCall(request).execute()) {
                    msg.obj = response.body().string();
                } catch (Exception e) {
                    e.printStackTrace();
                    msg.obj = e.getMessage();
                } finally {
                    handler.sendMessage(msg);
                }
            }
        }.start();
    }

    private void download() {
        String url = "https://tdui.td0f7.cn/1.jpeg";
        Request request = new Request.Builder().url(url).build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                Message msg = handler.obtainMessage(1);
                msg.obj = e.getMessage();
                handler.sendMessage(msg);
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                Sink sink = null;//写入用的
                BufferedSink bufferedSink = null;//sink写入
                InputStream is = null;
                FileOutputStream outputStream = null;
                String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/";//拿到sd卡目录
                File file = new File(path + url.substring(url.lastIndexOf("/") + 1));//获取文件名称，拼接完整下载路径+文件名
                sink = Okio.sink(file);
                bufferedSink = Okio.buffer(sink);
                is = response.body().byteStream();//拿到下载的流
                if (is != null) {
                    outputStream = new FileOutputStream(file);//如果下载的流不为空，则创建outputStream准备写入
                    byte[] bytes = new byte[1024];//每次写入的大小，1024比1 快1024倍 以此类推
                    int ch;//每次写入的数据
                    while ((ch = is.read(bytes)) != -1) {//is.read(bytes)的值给ch，如果ch不是-1代表没有写完
                        outputStream.write(bytes, 0, ch);//写入数据
                    }
                    //source 是读取的东西
                    bufferedSink.writeAll(response.body().source());//写入所有读取的东西

                    outputStream.close();//关闭不用的对象
                    bufferedSink.close();
                    sink.close();

                    Message msg = handler.obtainMessage(1);
                    msg.obj = "下载成功";
                    handler.sendMessage(msg);
                }
            }
        });
    }

    private void downloadProgress() {
        OkhttpUtil.download(new ProgressListener() {
            @Override
            public void onProgress(ProgressModel model) {
                //主线程
                long count = model.getCurrent() * 100 / model.getLenght();
                tvContent.setText("当前下载：" + count + "%" + "\n是否完成" + model.isDone());
            }
        }, new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        tvContent.setText("请求错误\n" + e.getMessage());
                    }
                });
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                if (response != null) {
                    String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + "1.png";
                    InputStream is = response.body().byteStream();
                    FileOutputStream fos = new FileOutputStream(new File(path));
                    int len = 0;
                    byte[] bytes = new byte[2048];
                    while (-1 != (len = is.read(bytes))) {
                        fos.write(bytes, 0, len);
                    }
                    fos.flush();
                    fos.close();
                    is.close();
                }
            }
        });
    }
}